{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<center>\n",
    "<img src=\"../../img/ods_stickers.jpg\">\n",
    "## Открытый курс по машинному обучению. Сессия № 2\n",
    "</center>\n",
    "Автор материала: программист-исследователь Mail.ru Group, старший преподаватель Факультета Компьютерных Наук ВШЭ Юрий Кашницкий. Материал распространяется на условиях лицензии [Creative Commons CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/). Можно использовать в любых целях (редактировать, поправлять и брать за основу), кроме коммерческих, но с обязательным упоминанием автора материала."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# <center>Тема 3. Обучение с учителем. Методы классификации\n",
    "## <center>Практика. Дерево решений в задаче предсказания выживания пассажиров \"Титаника\". Решение"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Заполните код в клетках и выберите ответы в [веб-форме](https://goo.gl/TBwVhQ).**\n",
    "\n",
    "**<a href=\"https://www.kaggle.com/c/titanic\">Соревнование</a> Kaggle \"Titanic: Machine Learning from Disaster\".**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.metrics import accuracy_score, confusion_matrix, roc_auc_score\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.tree import DecisionTreeClassifier, export_graphviz\n",
    "\n",
    "%matplotlib inline\n",
    "import seaborn as sns\n",
    "from matplotlib import pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Функция для формирования csv-файла посылки на Kaggle:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def write_to_submission_file(\n",
    "    predicted_labels,\n",
    "    out_file,\n",
    "    train_num=891,\n",
    "    target=\"Survived\",\n",
    "    index_label=\"PassengerId\",\n",
    "):\n",
    "    # turn predictions into data frame and save as csv file\n",
    "    predicted_df = pd.DataFrame(\n",
    "        predicted_labels,\n",
    "        index=np.arange(train_num + 1, train_num + 1 + predicted_labels.shape[0]),\n",
    "        columns=[target],\n",
    "    )\n",
    "    predicted_df.to_csv(out_file, index_label=index_label)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Считываем обучающую и тестовую выборки.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_df = pd.read_csv(\"../../data/titanic_train.csv\")\n",
    "test_df = pd.read_csv(\"../../data/titanic_test.csv\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = train_df[\"Survived\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_df.describe(include=\"all\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_df.describe(include=\"all\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Заполним пропуски медианными значениями.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_df[\"Age\"].fillna(train_df[\"Age\"].median(), inplace=True)\n",
    "test_df[\"Age\"].fillna(train_df[\"Age\"].median(), inplace=True)\n",
    "train_df[\"Embarked\"].fillna(\"S\", inplace=True)\n",
    "test_df[\"Fare\"].fillna(train_df[\"Fare\"].median(), inplace=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Кодируем категориальные признаки `Pclass`, `Sex`, `SibSp`, `Parch` и `Embarked` с помощью техники One-Hot-Encoding.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_df = pd.concat(\n",
    "    [\n",
    "        train_df,\n",
    "        pd.get_dummies(train_df[\"Pclass\"], prefix=\"PClass\"),\n",
    "        pd.get_dummies(train_df[\"Sex\"], prefix=\"Sex\"),\n",
    "        pd.get_dummies(train_df[\"SibSp\"], prefix=\"SibSp\"),\n",
    "        pd.get_dummies(train_df[\"Parch\"], prefix=\"Parch\"),\n",
    "        pd.get_dummies(train_df[\"Embarked\"], prefix=\"Embarked\"),\n",
    "    ],\n",
    "    axis=1,\n",
    ")\n",
    "test_df = pd.concat(\n",
    "    [\n",
    "        test_df,\n",
    "        pd.get_dummies(test_df[\"Pclass\"], prefix=\"PClass\"),\n",
    "        pd.get_dummies(test_df[\"Sex\"], prefix=\"Sex\"),\n",
    "        pd.get_dummies(test_df[\"SibSp\"], prefix=\"SibSp\"),\n",
    "        pd.get_dummies(test_df[\"Parch\"], prefix=\"Parch\"),\n",
    "        pd.get_dummies(test_df[\"Embarked\"], prefix=\"Embarked\"),\n",
    "    ],\n",
    "    axis=1,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_df.drop(\n",
    "    [\n",
    "        \"Survived\",\n",
    "        \"Pclass\",\n",
    "        \"Name\",\n",
    "        \"Sex\",\n",
    "        \"SibSp\",\n",
    "        \"Parch\",\n",
    "        \"Ticket\",\n",
    "        \"Cabin\",\n",
    "        \"Embarked\",\n",
    "        \"PassengerId\",\n",
    "    ],\n",
    "    axis=1,\n",
    "    inplace=True,\n",
    ")\n",
    "test_df.drop(\n",
    "    [\n",
    "        \"Pclass\",\n",
    "        \"Name\",\n",
    "        \"Sex\",\n",
    "        \"SibSp\",\n",
    "        \"Parch\",\n",
    "        \"Ticket\",\n",
    "        \"Cabin\",\n",
    "        \"Embarked\",\n",
    "        \"PassengerId\",\n",
    "    ],\n",
    "    axis=1,\n",
    "    inplace=True,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**В тестовой выборке появляется новое значение Parch = 9, которого нет в обучающей выборке. Проигнорируем его.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_df.shape, test_df.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "set(test_df.columns) - set(train_df.columns)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_df.drop([\"Parch_9\"], axis=1, inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Дерево решений без настройки параметров "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Обучите на имеющейся выборке дерево решений (`DecisionTreeClassifier`) максимальной глубины 2. Используйте параметр `random_state=17` для воспроизводимости результатов.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Ваш код здесь"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Сделайте с помощью полученной модели прогноз для тестовой выборки **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Ваш код здесь"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Сформируйте файл посылки и отправьте на Kaggle**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Ваш код здесь"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color='red'>Вопрос 1. </font> Каков результат первой посылки (дерево решений без настройки параметров) в публичном рейтинге соревнования Titanic?\n",
    "- 0.746\n",
    "- 0.756\n",
    "- 0.766\n",
    "- 0.776"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Отобразите дерево с помощью `export_graphviz` и `dot`.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Ваш код здесь"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color='red'>Вопрос 2. </font> Сколько признаков задействуются при прогнозе деревом решений глубины 2?\n",
    "- 2\n",
    "- 3\n",
    "- 4\n",
    "- 5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Дерево решений с настройкой параметров "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Обучите на имеющейся выборке дерево решений (`DecisionTreeClassifier`). Также укажите `random_state=17`. Максимальную глубину и минимальное число элементов в листе настройте на 5-кратной кросс-валидации с помощью `GridSearchCV`.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# tree params for grid search\n",
    "tree_params = {\"max_depth\": list(range(1, 5)), \"min_samples_leaf\": list(range(1, 5))}\n",
    "\n",
    "# Ваш код здесь"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color='red'>Вопрос 3. </font> Каковы лучшие параметры дерева, настроенные на кросс-валидации с помощью `GridSearchCV`?\n",
    "- max_depth=2, min_samples_leaf=1\n",
    "- max_depth=2, min_samples_leaf=4\n",
    "- max_depth=3, min_samples_leaf=2\n",
    "- max_depth=3, min_samples_leaf=3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color='red'>Вопрос 4. </font> Какой получилась средняя доля верных ответов на кросс-валидации для дерева решений с лучшим сочетанием гиперпараметров `max_depth` и `min_samples_leaf`?\n",
    "- 0.77\n",
    "- 0.79\n",
    "- 0.81\n",
    "- 0.83"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Сделайте с помощью полученной модели прогноз для тестовой выборки.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Ваш код здесь"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Сформируйте файл посылки и отправьте на Kaggle.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Ваш код здесь"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color='red'>Вопрос 5. </font> Каков результат второй посылки (дерево решений с настройкой гиперпараметров) в публичном рейтинге соревнования Titanic?\n",
    "- 0.7499\n",
    "- 0.7599\n",
    "- 0.7699\n",
    "- 0.7799"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ссылки:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " - <a href=\"https://www.kaggle.com/c/titanic\">Соревнование</a> Kaggle \"Titanic: Machine Learning from Disaster\"\n",
    " - <a href=\"https://www.dataquest.io/mission/74/getting-started-with-kaggle/\">Тьюториал</a> Dataquest по задаче Kaggle \"Titanic: Machine Learning from Disaster\""
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  },
  "name": "lesson3_homework_trees_titanic_solution.ipynb"
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
